package com.qsl.ssyx.cart.service.impl;

import com.qsl.ssyx.cart.service.CartService;
import com.qsl.ssyx.client.product.ProductFeignClient;
import com.qsl.ssyx.common.constant.RedisConst;
import com.qsl.ssyx.common.exception.BusinessException;
import com.qsl.ssyx.common.result.ResultCodeEnum;
import com.qsl.ssyx.enums.SkuType;
import com.qsl.ssyx.model.order.CartInfo;
import com.qsl.ssyx.model.product.SkuInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ProductFeignClient productFeignClient;

    // 根据用户id获取Redis里的Key    例：user:userId:cart
    private String getCartKey(Long userId) {
//        例：user:5:cart
        return RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
    }

    //    根据用户id，商品Id,商品数量加入Redis-添加商品进购物车
    @Override
    public void addToCart(Long userId, Long skuId, Integer skuNum) {
        // 1. 获取Redis
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);

        CartInfo cartInfo = null;
        // 根据skuId判断Redis是否第一次将这个商品添加到购物车
//        判断指定key中是否存在该键   存在：为修改，否则为新增
        if (hashOperations.hasKey(skuId.toString())) { // 修改
            // 根据商品id获取商品信息
            cartInfo = hashOperations.get(skuId.toString());
            // 商品数量+1
            Integer currentSkuNum = cartInfo.getSkuNum() + skuNum;
            if (currentSkuNum < 1) {
                return;
            }

            // 根据cartInfo对象
            cartInfo.setSkuNum(currentSkuNum); // 商品加入购物车的数量
            cartInfo.setCurrentBuyNum(currentSkuNum); //当天已购买个数

            // 判断购物车商品数量是否大于限购数量
            Integer perLimit = cartInfo.getPerLimit();
            if (currentSkuNum > perLimit) {
                throw new BusinessException(ResultCodeEnum.SKU_LIMIT_ERROR);
            }

            // 更新其他值
            cartInfo.setIsChecked(1);
            cartInfo.setUpdateTime(new Date());
        } else { // 新增
            // 商品数量+1
            skuNum = 1;

            // 根据skuId获取skuInfo-商品信息
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            if (skuInfo == null) {
                throw new BusinessException(ResultCodeEnum.DATA_ERROR);
            }

            // 封装数据
            cartInfo = new CartInfo();
            BeanUtils.copyProperties(skuInfo, cartInfo);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCurrentBuyNum(skuNum);  // 当天已购买个数
            cartInfo.setSkuType(SkuType.COMMON.getCode());
            cartInfo.setIsChecked(1);
            cartInfo.setStatus(1);
            cartInfo.setCreateTime(new Date());
            cartInfo.setUpdateTime(new Date());

            //5 更新redis缓存
            hashOperations.put(skuId.toString(), cartInfo);

            // 设置有效时间
            this.setCartKeyExpire(cartKey);
        }
    }

    //    根据商品Id及用户id删除购物车商品
    @Override
    public void deleteCartBySkuId(Long skuId, Long userId) {
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(this.getCartKey(userId));
        // 判断Redis的是否存在，存在删除
        if (hashOperations.hasKey(skuId.toString())) {
            hashOperations.delete(skuId.toString());
        }
    }

    //    根据用户Id清空购物车商品
    @Override
    public void deleteAllCart(Long userId) {
        String cartKey = this.getCartKey(userId);
        // 根据key查询Redis购物车信息
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
//        判断Redis是否存在当前用户的购物车信息-存在删除
        List<CartInfo> cartInfoList = hashOperations.values();
        // 遍历删除
        for (CartInfo cartInfo : cartInfoList) {
            hashOperations.delete(cartInfo.getId().toString());
        }
    }

    //    根据用户Id清空购物车商品-批量删除
    @Override
    public void batchDeleteCart(Long userId, List<Long> skuIdList) {
        String cartKey = this.getCartKey(userId);
        // 根据key查询购物车信息
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 获取购物车集合所有信息
        List<CartInfo> cartInfoList = hashOperations.values();
        for (Long skuId : skuIdList) {
            // 删除
            hashOperations.delete(skuId.toString());
        }
    }

    //    根据用户Id获取-购物车商品列表
    @Override
    public List<CartInfo> getCartList(Long userId) {
        // 封装最终返回数据
        List<CartInfo> cartInfoList = null;
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 获取所有购物车信息
        cartInfoList = hashOperations.values();

        // 集合不为空，根据商品添加时间排序-降序
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList.sort(new Comparator<CartInfo>() {
                @Override
                public int compare(CartInfo o1, CartInfo o2) {
                    return o1.getCreateTime().compareTo(o2.getCreateTime());
                }
            });
        }
        return cartInfoList;
    }

    // 修改Redis购物车商品选中状态
    @Override
    public void checkCart(Long userId, Integer isChecked, Long skuId) {
        // 获取redis的key
        String cartKey = this.getCartKey(userId);
        // 根据key获取redis中的field和value值
        BoundHashOperations<String, String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        // 根据field(skuId)获取value(Cartinfo)
        CartInfo cartInfo = boundHashOperations.get(skuId.toString());

        // 不为空，修改购物车商品选中状态
        if (cartInfo != null) {
            cartInfo.setIsChecked(isChecked);
            // 更新
            boundHashOperations.put(skuId.toString(), cartInfo);
            // 设置key过期时间
            this.setCartKeyExpire(cartKey);
        }
    }

    // 修改Redis购物车商品选中状态-全选/全不选
    @Override
    public boolean checkAllCart(Long userId, Integer isChecked) {
        String cartKey = this.getCartKey(userId);
        // 根据key获取哈希值的filed和val值
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 获取哈希值的所有val数据
        List<CartInfo> cartInfoList = hashOperations.values();

        for (CartInfo cartInfo : cartInfoList) {
            cartInfo.setIsChecked(isChecked);
            hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
        }
        return true;
    }

    // 修改Redis购物车商品选中状态-批量选中
    @Override
    public boolean batchCheckCart(List<Long> skuIdList, Long userId, Integer isChecked) {
        String cartKey = this.getCartKey(userId);
        // 根据key获取filed和val
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        for (Long skuId : skuIdList) {
            CartInfo cartInfo = hashOperations.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOperations.put(cartInfo.getSkuId().toString(), cartInfo);
        }
        // Redis设置key 过期时间
        this.setCartKeyExpire(cartKey);

        return true;
    }


    //    获取购物车里选中的商品-根据用户Id
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        String cartKey = this.getCartKey(userId);

        // 获取哈希列表
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 获取哈希的所有val值
        List<CartInfo> cartInfoList = hashOperations.values();
        // 获取购物车所有选中的商品
        List<CartInfo> cartInfoListNew = cartInfoList.stream().filter(item -> item.getIsChecked().intValue() == 1).collect(Collectors.toList());

        return cartInfoListNew;
    }

    //    根据用户id,获取当前用户购物车商品（选中的购物项）
    @Override
    public List<CartInfo> getCartListByUserId(Long userId) {
        String cartKey = this.getCartKey(userId);
        // 根据key获取哈希的filed，val。
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 获取哈希的val
        List<CartInfo> cartInfoList = hashOperations.values();
        // 获取所有用户购物车选中的商品
        List<CartInfo> cartInfoListIsChecked = cartInfoList.stream().filter(item -> item.getIsChecked() == 1).collect(Collectors.toList());
        return cartInfoListIsChecked;
    }

    // Redis设置key 过期时间
    public void setCartKeyExpire(String key) {
        redisTemplate.expire(key, RedisConst.USER_CART_EXPIRE, TimeUnit.SECONDS);
    }
}
